package com.zbystudy.core;

import com.zbystudy.anno.ManyToOne;
import com.zbystudy.factory.PackageEntityFactory;
import com.zbystudy.util.ArrayUtil;

import java.lang.reflect.Field;
import java.util.*;

import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.replace;

/**
 * Created By zby on 21:14 2019/4/2
 * 实体类的层级关系,根据多对一的层级关系
 */

public class EntityPriority {

    /**
     * 实体类的优先级
     */
    private static Map<String, Integer> entityPathMap = new HashMap<>();

    private static String ENTITY_PATH = "";

    /**
     * 初始权重
     */
    private static Integer INIT_PRIORITY = 1;

    /**
     * Created By zby on 23:31 2019/4/2
     * 获取排序后的值
     */
    public static Set<String> sortEntityPath() {
        int maxPriority = getMaxPriority();
        Set<String> entityPathSet = new LinkedHashSet<>();
        for (int i = 1; i <= maxPriority; i++) {
            if (entityPathMap != null && entityPathMap.size() > 0) {
                for (Map.Entry<String, Integer> entry : entityPathMap.entrySet()) {
                    int value = entry.getValue();
                    if (value == i) {
                        entityPathSet.add(entry.getKey());
                    }
                }
            }
        }
        return entityPathSet;
    }

    /**
     * Created By zby on 23:17 2019/4/2
     * 获取最大权重值
     */
    public static Integer getMaxPriority() {
        setEntityPath(INIT_PRIORITY);
//        最大权重值
        int maxPriority = 1;
        if (entityPathMap != null && entityPathMap.size() > 0) {
            for (Map.Entry<String, Integer> entry : entityPathMap.entrySet()) {
                int value = entry.getValue();
                if (value > maxPriority) {
                    maxPriority = value;
                }
            }
        }
        return maxPriority;
    }

    /**
     * Created By zby on 21:36 2019/4/2
     * 设置实体类的名字
     */
    private static void setEntityPath(Integer priority) {
        List<String> entityFilePaths = PackageEntityFactory.getInstance()
                .loadEntityFileNames("jdbc.package", true);
        for (String entityPath : entityFilePaths) {
            ENTITY_PATH = entityPath;
            setPriority(entityPath, priority, null);
        }
    }

    /**
     * Created By zby on 23:22 2019/4/2
     * 设置权重
     *
     * @param entityPath    实体类的路径
     * @param priority      权重值
     * @param fieldTypeName 属性类型名称
     */
    private static void setPriority(String entityPath, Integer priority, String fieldTypeName) {
        try {
            Class clazz = Class.forName(isNotBlank(entityPath) ? entityPath : fieldTypeName);
            Field[] fields = clazz.getDeclaredFields();
            if (ArrayUtil.isNotEmpty(fields)) {
                boolean hasManyToOne = false;
                for (Field field : fields) {
                    ManyToOne manyToOne = field.getDeclaredAnnotation(ManyToOne.class);
                    if (null != manyToOne) {
                        fieldTypeName = field.getType().getName();
                        hasManyToOne = true;
                        break;
                    }
                }
                if (hasManyToOne) {
                    setPriority(null, ++priority, fieldTypeName);
                } else {
                    entityPathMap.put(ENTITY_PATH, priority);
                }
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
